iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 10
0
Modern Web

在Three.js探索CAD的奧秘系列 第 10

Day 10 : 射線法點選網格

  • 分享至 

  • xImage
  •  

前言

Raycaster射線法,是指在場景中打出一條射線,紀錄打出去的射線所有經過的網格,並且計算出與三角網格的交點,若沒有經過任何網格則不進行網格的紀錄。

射線經過網格

在CAD軟體的應用中,如何找到點選的對象是個基本且重要的問題,下圖是表示空間中的一群網格資料,並在空間中打出一條藍色的射線,紅色的點表示射線經過網格的位置。

https://ithelp.ithome.com.tw/upload/images/20171229/20107175xj2mSVmGIj.png
一條射線經過了網格

使用Three.js內建的Raycaster

首先在宣告區增加intersects用來存放取得的資料點。

this.intersects = [];

接著在init加入兩個監聽式mousedown、mouseup並指向兩個函數onMouseDown、onMouseUp。

//滑鼠設定
self.container.addEventListener('mousedown', self.onMouseDown.bind(self), false);
self.container.addEventListener('mouseup', self.onMouseUp.bind(self), false);

然後要注意到TrackballControls的第二個參數需要使用的是container,這裡需要修正一下否則會點選不到container。

self.controls = new TrackballControls(
    self.camera,
    self.container
);

再建立一個滑鼠點選時的onMouseDown事件的函數,其中透過JavaScript內建函數取得mouse的座標,並且從相機去設定raycaster與滑鼠的關係,再透過intersectObjects取得目前場景中所有射線打中的物件。若有打中空間中物件,intersects的陣列就會有複數以上的資料。

Viewer.prototype.onMouseDown = function (event) {
    var self = this;
    
    self.mouse.x = (event.clientX / window.innerWidth ) * 2 - 1;
    self.mouse.y = - (event.clientY / window.innerHeight ) * 2 + 1;

    self.raycaster.setFromCamera(self.mouse, self.camera);

    self.intersects = self.raycaster.intersectObjects(self.scene.children);

    //Do Something
};

值得注意的是為了在我們點選的過程中讓TrackballControls停止作用,要給controls.enabled一個false的布林值來暫時關閉,這樣滑鼠點選到物件後就不會有旋轉平移的功能。

if (self.intersects.length > 0) {
    self.controls.enabled = false;

    //Draw Something
}

本文做一個簡單的應用,在點選的位置畫出一顆球,使用先前教過的語法就能輕鬆完成囉,順帶一提要在meshs也push球的資訊,才能在Clear的時後也把球給一併清除掉。

var geometry = new THREE.SphereBufferGeometry(0.5, 16, 16);
var material = new THREE.MeshPhongMaterial({
    color: 0xff0000
});
var mesh = new THREE.Mesh(geometry, material);

mesh.position.copy(self.intersects[0].point);
self.scene.add(mesh);

self.meshs.push(mesh);

最後還要建立一個onMouseUp函數,用來在放開滑鼠後能夠將TrackballControls給從新啟用回來,下圖是本次的繪圖結果。

Viewer.prototype.onMouseUp = function (event) {
    var self = this;
    self.controls.enabled = true;
};

https://i.imgur.com/iV3okc4.gif
在monkey.stl上面畫圓球

範例原始碼

https://github.com/QQBoxy/threecad/blob/master/client/example7/Viewer.js

後記

這次介紹了一個建立CAD軟體所需的選擇功能,在後續的範例中將會大量的使用此語法,此方法很重要大家務必要學會使用喔。


上一篇
Day 9 : 基本相機控制
下一篇
Day 11 : 三角網格拓樸關係
系列文
在Three.js探索CAD的奧秘30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言